{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a9d0b1f85e7f20cb",
   "metadata": {},
   "source": [
    "### Building a ChemProp model with RDKit descriptors\n",
    "\n",
    "This notebook shows how to build a ChemProp model using RDKit descriptors as additional features.  The notebook borrows heavily from the ChemProp examples. \n",
    "1. Read the input data\n",
    "2. Divide the dataset into training, validation, and test sets\n",
    "3. Calculate RDKit descriptors\n",
    "4. Create the datasets\n",
    "5. Create dataloaders\n",
    "6. Create the model\n",
    "7. Train the model\n",
    "8. Predict the values for the test set\n",
    "9. Evaluate the model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d1433b9d3ff861e7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:19:46.441415Z",
     "start_time": "2024-07-30T17:19:44.235679Z"
    }
   },
   "outputs": [],
   "source": [
    "import itertools\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import useful_rdkit_utils as uru\n",
    "from chemprop import data, featurizers, nn, models\n",
    "from lightning import pytorch as pl\n",
    "from sklearn.metrics import r2_score, root_mean_squared_error\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea5a0149-5a99-457d-a7b1-8e6d4d478238",
   "metadata": {},
   "source": [
    "### 1. Read the input data\n",
    "Read the input data. For this exercise, we'll use one of the datasets from [this paper by Fang et al](https://pubs.acs.org/doi/10.1021/acs.jcim.3c00160). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "3f4772a9-6a1f-4278-bf43-e9bdb14e4b87",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:19:46.448211Z",
     "start_time": "2024-07-30T17:19:46.442406Z"
    }
   },
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"https://raw.githubusercontent.com/PatWalters/practical_cheminformatics_tutorials/main/chemprop/data/biogen_logS.csv\")\n",
    "y_col = \"logS\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b8c2245-bf8d-465f-aad6-5168f8e86a94",
   "metadata": {},
   "source": [
    "### 2. Divide the dataset into training, validation, and test sets\n",
    "Divide the dataset into training, validation, and test sets.  ChemProp has functions for dataset splitting, but I thought it might be useful to show how to do it with scikit-learn."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "49fe4b88f5b40163",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:24:16.514186Z",
     "start_time": "2024-07-30T17:24:16.459074Z"
    }
   },
   "outputs": [],
   "source": [
    "train_frac, val_frac, test_frac = 0.8, 0.1, 0.1\n",
    "train, test = train_test_split(df, test_size=test_frac)\n",
    "train, val = train_test_split(train, test_size=len(test))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d04c0c0f-1469-4399-a38d-7df53262fefd",
   "metadata": {},
   "source": [
    "Examine the sizes of the training, validation, and test sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7170d683-d9d1-4d21-9d19-9da0dafb18d2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:24:18.694027Z",
     "start_time": "2024-07-30T17:24:18.689324Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1737, 218, 218)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(train), len(val), len(test)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b60637b625627621",
   "metadata": {},
   "source": [
    "### 3. Calculate RDKit descriptors\n",
    "A small function to calculate RDKit descriptors using [useful_rdkit_utils](https://useful-rdkit-utils.readthedocs.io/en/latest/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8a6a19cc4135365e",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:24:23.142561Z",
     "start_time": "2024-07-30T17:24:23.138786Z"
    }
   },
   "outputs": [],
   "source": [
    "def calc_descriptors(smi_list):\n",
    "    generator = uru.RDKitDescriptors()\n",
    "    return generator.pandas_smiles(smi_list).values.tolist()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "575148638ecee979",
   "metadata": {},
   "source": [
    "Calculate the RDKit descriptors for the training, validation, and test sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b28df94985f2f157",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:24:46.525440Z",
     "start_time": "2024-07-30T17:24:25.601627Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f73908b0c5fe45dab7f484aff910c8cc",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/1737 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8e12a5970c784940a7cae1647d970bbd",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/218 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a29e3154c7ba4055961331e3e83c9b97",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/218 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "train['feat'] = calc_descriptors(train.SMILES.values)\n",
    "val['feat'] = calc_descriptors(val.SMILES.values)\n",
    "test['feat'] = calc_descriptors(test.SMILES.values)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81d3eaa90f9efdc2",
   "metadata": {},
   "source": [
    "### 4. Create the datasets\n",
    "Convert the data to MoleculeDatapoints.  We're adding extra molecule features, so we use the **x_d** argument in **data.MoleculeDatapoint.from_smi**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "33f7350272b2b4f7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:24:57.674111Z",
     "start_time": "2024-07-30T17:24:57.490786Z"
    }
   },
   "outputs": [],
   "source": [
    "cols = [\"SMILES\", y_col, 'feat']\n",
    "train_pt = [data.MoleculeDatapoint.from_smi(smi, [y], x_d=np.array(X_d)) for smi, y, X_d in train[cols].values]\n",
    "val_pt = [data.MoleculeDatapoint.from_smi(smi, [y], x_d=np.array(X_d)) for smi, y, X_d in val[cols].values]\n",
    "test_pt = [data.MoleculeDatapoint.from_smi(smi, [y], x_d=np.array(X_d)) for smi, y, X_d in test[cols].values]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02531c9b-20a2-4cb2-9f11-615f2e3359c6",
   "metadata": {},
   "source": [
    "Create a featurizer to generate graph node and edge features for the molecules."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f10597d22823a4d8",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:25:01.403070Z",
     "start_time": "2024-07-30T17:25:01.400822Z"
    }
   },
   "outputs": [],
   "source": [
    "featurizer = featurizers.SimpleMoleculeMolGraphFeaturizer()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6038f4f-245a-4a7f-9e42-535adde00256",
   "metadata": {},
   "source": [
    "Create a training dataset by featurizing the training set, and normalizing the targets. Create another scaler for the added descriptors. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "549b79b9936a1d66",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:25:53.088722Z",
     "start_time": "2024-07-30T17:25:53.074386Z"
    }
   },
   "outputs": [],
   "source": [
    "train_dset = data.MoleculeDataset(train_pt, featurizer)\n",
    "scaler = train_dset.normalize_targets()\n",
    "extra_datapoint_descriptors_scaler = train_dset.normalize_inputs(\"X_d\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d69c66a-80e0-40c9-b80a-5798a77ce105",
   "metadata": {},
   "source": [
    "Do the same with the validation dataset.  Use the scalers we created for the training set to scale the validation set descriptors and targets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "5656fc28-72ea-466f-8215-2271be5106a7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:26:27.014413Z",
     "start_time": "2024-07-30T17:26:27.007303Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;StandardScaler<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.4/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "StandardScaler()"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val_dset = data.MoleculeDataset(val_pt, featurizer)\n",
    "val_dset.normalize_targets(scaler)\n",
    "val_dset.normalize_inputs(\"X_d\", extra_datapoint_descriptors_scaler)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55f29e5f-00d9-4b75-9472-74a2b0971823",
   "metadata": {},
   "source": [
    "Create the test dataset  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "1689fb59-30b8-485d-925e-20d9a61d687f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:26:32.118836Z",
     "start_time": "2024-07-30T17:26:32.114564Z"
    }
   },
   "outputs": [],
   "source": [
    "test_dset = data.MoleculeDataset(test_pt, featurizer)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9a591c7-ec12-42ba-9449-77fe4e433f5a",
   "metadata": {},
   "source": [
    "### 5. Create dataloaders\n",
    "Create dataloaders for the training validation and test sets.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "22fb820e-478c-4294-90fe-85d91afd2710",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:26:34.380263Z",
     "start_time": "2024-07-30T17:26:34.351413Z"
    }
   },
   "outputs": [],
   "source": [
    "num_workers = 0\n",
    "train_loader = data.build_dataloader(train_dset, num_workers=num_workers)\n",
    "val_loader = data.build_dataloader(val_dset, num_workers=num_workers, shuffle=False)\n",
    "test_loader = data.build_dataloader(test_dset, num_workers=num_workers, shuffle=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80b3f796-28c5-4282-a08f-ff3569f56cf6",
   "metadata": {},
   "source": [
    "### 6. Create the model\n",
    "Create the Feed Forward Neural Network (FFNN)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "582d0a76-1c0c-4ed7-b79d-1eaf5d1044e6",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:26:36.736835Z",
     "start_time": "2024-07-30T17:26:36.724117Z"
    }
   },
   "outputs": [],
   "source": [
    "num_extra_features = len(train.feat.values[0])\n",
    "mp = nn.BondMessagePassing()\n",
    "ffn_input_dim = mp.output_dim + num_extra_features\n",
    "output_transform = nn.UnscaleTransform.from_standard_scaler(scaler)\n",
    "ffn = nn.RegressionFFN(input_dim=ffn_input_dim, output_transform=output_transform)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec46f74c-17b6-4117-9043-5a0cf03bcb3b",
   "metadata": {},
   "source": [
    "Create the Message Passing Neural Network (MPNN)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "2d8e598d398e9561",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:26:39.225651Z",
     "start_time": "2024-07-30T17:26:39.218376Z"
    }
   },
   "outputs": [],
   "source": [
    "batch_norm = True\n",
    "agg = nn.MeanAggregation()\n",
    "metric_list = [nn.metrics.RMSEMetric()]\n",
    "X_d_transform = nn.ScaleTransform.from_standard_scaler(extra_datapoint_descriptors_scaler)\n",
    "mpnn = models.MPNN(mp, agg, ffn, metrics=metric_list, X_d_transform=X_d_transform, batch_norm=batch_norm)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3de6f4cc-0e70-4f84-af8c-511c8f2d4f60",
   "metadata": {},
   "source": [
    "### 7. Train the model\n",
    "Train the MPNN on the training and validation sets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "6b6b056c-cc56-4b4d-ae34-40de7df20f65",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:27:21.049234Z",
     "start_time": "2024-07-30T17:26:41.516132Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "GPU available: True (mps), used: False\n",
      "TPU available: False, using: 0 TPU cores\n",
      "IPU available: False, using: 0 IPUs\n",
      "HPU available: False, using: 0 HPUs\n",
      "/Users/pwalters/miniconda3/envs/chemprop/lib/python3.11/site-packages/lightning/pytorch/trainer/setup.py:187: GPU available but not used. You can set it by doing `Trainer(accelerator='gpu')`.\n",
      "Loading `train_dataloader` to estimate number of stepping batches.\n",
      "/Users/pwalters/miniconda3/envs/chemprop/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:441: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=9` in the `DataLoader` to improve performance.\n",
      "\n",
      "  | Name            | Type               | Params\n",
      "-------------------------------------------------------\n",
      "0 | message_passing | BondMessagePassing | 227 K \n",
      "1 | agg             | MeanAggregation    | 0     \n",
      "2 | bn              | BatchNorm1d        | 600   \n",
      "3 | predictor       | RegressionFFN      | 153 K \n",
      "4 | X_d_transform   | ScaleTransform     | 0     \n",
      "-------------------------------------------------------\n",
      "381 K     Trainable params\n",
      "0         Non-trainable params\n",
      "381 K     Total params\n",
      "1.528     Total estimated model params size (MB)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Sanity Checking: |                                                                                            …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/pwalters/miniconda3/envs/chemprop/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:441: The 'val_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=9` in the `DataLoader` to improve performance.\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "2af2b0541caa4ab1910428a63ce9283e",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Training: |                                                                                                   …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Validation: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "`Trainer.fit` stopped: `max_epochs=20` reached.\n"
     ]
    }
   ],
   "source": [
    "trainer = pl.Trainer(\n",
    "    logger=False,\n",
    "    enable_checkpointing=False,\n",
    "    enable_progress_bar=True,\n",
    "    accelerator=\"cpu\",\n",
    "    devices=1,\n",
    "    max_epochs=20,  # number of epochs to train for\n",
    ")\n",
    "trainer.fit(mpnn, train_loader, val_loader)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87660b3d-8b58-4d15-8fe1-ca09f5173eb4",
   "metadata": {},
   "source": [
    "### 8. Predict the values for the test set\n",
    "Predict the values for the test set. ChemProp returns the results from **predict** as an array of PyTorch tensors, which isn't particularly convenient. We'll fix that below. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "643529c0-c850-4879-a0ab-307d20a09fbd",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:27:30.852144Z",
     "start_time": "2024-07-30T17:27:30.669512Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/pwalters/miniconda3/envs/chemprop/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:441: The 'predict_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=9` in the `DataLoader` to improve performance.\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "3e49af8369234f0fa7b35d4ad144deb7",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Predicting: |                                                                                                 …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "pred_tensor = trainer.predict(mpnn, test_loader)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "8f5e663b-2ec3-4cf7-8ad2-39771bfe0242",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:27:33.519710Z",
     "start_time": "2024-07-30T17:27:33.516617Z"
    }
   },
   "outputs": [],
   "source": [
    "pred = np.array(list(itertools.chain(*pred_tensor))).flatten()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51041183295f35e0",
   "metadata": {},
   "source": [
    "### 9. Evaluate the model\n",
    "Plot the distribution of the predicted values. I just put this in to make sure the predictions look reasonable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "9d8507756084445f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:27:40.478575Z",
     "start_time": "2024-07-30T17:27:40.331874Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.FacetGrid at 0x329aabcd0>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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UpKdYwMAEDS2hvrUqVN64oknVFZWpoiICCUlJWnr1q168MEHdeLECW3fvl3Lli1TVVWVYmNjlZqaqpdeesnOkQEACCpbQ71y5cpGb4uNjVV+fn4QpwEAwDzGvUYNAAD+hlADAGAwQg0AgMEINQAABiPUAAAYjFADAGAwQg0AgMEINQAABiPUAAAYjFADAGAwQg0AgMEINQAABiPUAAAYjFADAGAwQg0AgMEINQAABiPUAAAYjFADAGAwQg0AgMEINQAABiPUAAAYjFADAGAwQg0AgMFC7R4AANB8xcXFttwXwUeoAaANqak8LSlEs2bNavFatd6LLR8IrY5QA0AbUlt9TpKlEY++oB7xiX6tUXaoQEXvv61Lly4Fdji0CkINAG1Ql55xioxL8Ou+nrLjgR0GrYo3kwEAYDBCDQCAwQg1AAAGI9QAABiMUAMAYDBCDQCAwQg1AAAG4/eoAaCJXC6X3G633/fn1J3wB6EGgCZwuVxKTBykmprqFq/FqTvRHIQaAJrA7XarpqZayU8vVrizr19rcOpO+INQA0AzhDv7cupOBBVvJgMAwGCEGgAAgxFqAAAMRqgBADCYraFevny5kpKSFB4ervDwcKWkpOijjz7y3X7hwgWlp6ere/fu6tKli1JTU1VRUWHjxAAABJetoe7du7dee+01FRYWau/evRo3bpymT5+uw4cPS5IWLVqkDz74QOvXr1d+fr6++uorPfzww3aODABAUNn661nTpk2rd/3VV1/V8uXLtWvXLvXu3VsrV67U2rVrNW7cOEnS6tWrNWjQIO3atUv33nuvHSMDABBUxrxGffnyZa1bt05VVVVKSUlRYWGhamtrNWHCBN8+iYmJiouLU0FBQaPreL1eeTyeehcAANoq20N96NAhdenSRQ6HQ88884w2btyowYMHq7y8XB07dlS3bt3q7R8dHa3y8vJG18vOzlZERITvEhsb28pHAABA67E91AkJCTpw4IB2796tefPmKS0tTZ999pnf62VmZqqystJ3OXHiRACnBQAguGw/hWjHjh01YMAASdLIkSO1Z88e/fznP9d3v/tdXbx4UWfPnq33rLqiokIxMTGNrudwOORwOFp7bAAAgsL2Z9TXqqurk9fr1ciRI9WhQwfl5ub6bispKZHL5VJKSoqNEwIAEDy2PqPOzMzUlClTFBcXp3Pnzmnt2rXK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",
      "text/plain": [
       "<Figure size 500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.displot(pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "8aaf6296-37f2-4ad3-8068-e859842982f9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:27:41.696452Z",
     "start_time": "2024-07-30T17:27:41.692909Z"
    }
   },
   "outputs": [],
   "source": [
    "pred_df = pd.DataFrame({y_col: test[y_col], 'pred': pred})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f5de4b0-eff6-42ad-a806-900a7494680b",
   "metadata": {},
   "source": [
    "Plot the experimental vs predicted values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "a8ec6416-e759-44f0-9394-43d803c6b817",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:27:45.830118Z",
     "start_time": "2024-07-30T17:27:45.653033Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<seaborn.axisgrid.FacetGrid at 0x340213390>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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e0y2a6brndjoeie+fFwzZdQZwPM8pk2blrHP53K5Js0Pfdxku2a63omNrnfiM9o1UzEZIYQQYmAUqAkhhBADo0CdI5Ik4Tvf+Q4kScr3UHJmsl0zXe/ERtc78Rn1mqmYjBBCCDEwyqgJIYQQA6NATQghhBgYBWpCCCHEwChQE0IIIQZGgTqLvv/972P58uWw2WwoKipK6zWMMTz44IOoqqqC1WrFqlWrcOjQoewONEO6u7vxxS9+ES6XC0VFRbjlllvg9/uHfc3KlSvBcVzS2+23356jEY/eY489hlNPPRUWiwXnnHMOdu/ePezz//jHP2LevHmwWCyoq6vDK6+8kqORZsZornfDhg2DvpcWiyWHox2ft956C1deeSWqq6vBcRxefPHFEV+zbds2nHHGGZAkCbNmzcKGDRuyPs5MGe31btu2bdD3l+M4eDye3Ax4nNavX4+zzz4bTqcT5eXlWLNmDRobG0d8nRF+hylQZ1EkEsE111yDO+64I+3X/PCHP8TPfvYzPPHEE9i1axfsdjtWr16NcDicxZFmxhe/+EUcPHgQW7ZswaZNm/DWW2/hq1/96oivu/XWW9Ha2pp4++EPf5iD0Y7eCy+8gLVr1+I73/kO/vGPf2Dx4sVYvXo12tvbUz5/x44duO6663DLLbdg7969WLNmDdasWYMDBw7keORjM9rrBfSOTv2/l59++mkORzw+gUAAixcvxmOPPZbW848cOYLLL78cn/3sZ7Fv3z7cc889+MpXvoLXXnstyyPNjNFeb1xjY2PS97i8vDxLI8ys7du3484778S7776LLVu2IBqN4uKLL0YgEBjyNYb5HWYk655++mnmdrtHfJ6maayyspL96Ec/SjzW29vLJElizz//fBZHOH4ffvghA8Dee++9xGOvvvoq4ziOHT9+fMjXrVixgn3961/PwQjHb+nSpezOO+9MvK+qKquurmbr169P+fx//ud/ZpdffnnSY+eccw677bbbsjrOTBnt9ab7c14IALCNGzcO+5z77ruPLViwIOmxL3zhC2z16tVZHFl2pHO9b775JgPAenp6cjKmbGtvb2cA2Pbt24d8jlF+hymjNpAjR47A4/Fg1apVicfcbjfOOecc7Ny5M48jG9nOnTtRVFSEs846K/HYqlWrwPM8du3aNexrf//736O0tBQLFy7EunXrEAwGsz3cUYtEItizZ0/S94bneaxatWrI783OnTuTng8Aq1evNvz3Ehjb9QKA3+/HKaecgpqaGlx11VU4ePBgLoabF4X8/R2PJUuWoKqqChdddBHeeeedfA9nzLxeLwCgpKRkyOcY5XtMh3IYSHytp6KiIunxiooKw68DeTyeQVNgoiiipKRk2LFff/31OOWUU1BdXY39+/fj29/+NhobG/HnP/8520Melc7OTqiqmvJ789FHH6V8jcfjKcjvJTC26507dy5++9vfYtGiRfB6vfjxj3+M5cuX4+DBgxk92MYohvr++nw+hEIhWK3WPI0sO6qqqvDEE0/grLPOgizLeOqpp7By5Urs2rULZ5xxRr6HNyqapuGee+7Beeedh4ULFw75PKP8DlOgHqX7778fjzzyyLDPaWhowLx583I0ouxK93rHqv8adl1dHaqqqnDhhReiubkZM2fOHPPnJbm3bNkyLFu2LPH+8uXLMX/+fDz55JP43ve+l8eRkUyYO3cu5s6dm3h/+fLlaG5uxk9+8hM8++yzeRzZ6N155504cOAA3n777XwPJS0UqEfp3nvvxU033TTsc2pra8f0uSsrKwEAbW1tqKqqSjze1taGJUuWjOlzjle611tZWTmoyEhRFHR3dyeuKx3nnHMOAKCpqclQgbq0tBSCIKCtrS3p8ba2tiGvr7KyclTPN5KxXO9AJpMJp59+OpqamrIxxLwb6vvrcrkmXDY9lKVLlxZMsIu76667EsWuI830GOV3mNaoR6msrAzz5s0b9s1sNo/pc8+YMQOVlZXYunVr4jGfz4ddu3YlZSq5lO71Llu2DL29vdizZ0/itW+88QY0TUsE33Ts27cPAJJuVIzAbDbjzDPPTPreaJqGrVu3Dvm9WbZsWdLzAWDLli15+16OxliudyBVVVFfX2+472WmFPL3N1P27dtXMN9fxhjuuusubNy4EW+88QZmzJgx4msM8z3OaenaJPPpp5+yvXv3soceeog5HA62d+9etnfvXtbX15d4zty5c9mf//znxPv/+Z//yYqKithf/vIXtn//fnbVVVexGTNmsFAolI9LGJVLLrmEnX766WzXrl3s7bffZrNnz2bXXXdd4uPHjh1jc+fOZbt27WKMMdbU1MQefvhh9v7777MjR46wv/zlL6y2tpZdcMEF+bqEYf3v//4vkySJbdiwgX344Yfsq1/9KisqKmIej4cxxtiXvvQldv/99yee/8477zBRFNmPf/xj1tDQwL7zne8wk8nE6uvr83UJozLa633ooYfYa6+9xpqbm9mePXvYtddeyywWCzt48GC+LmFU+vr6Er+jANijjz7K9u7dyz799FPGGGP3338/+9KXvpR4/uHDh5nNZmPf+ta3WENDA3vssceYIAhs8+bN+bqEURnt9f7kJz9hL774Ijt06BCrr69nX//61xnP8+xvf/tbvi5hVO644w7mdrvZtm3bWGtra+ItGAwmnmPU32EK1Fl04403MgCD3t58883EcwCwp59+OvG+pmns3//931lFRQWTJIldeOGFrLGxMfeDH4Ouri523XXXMYfDwVwuF7v55puTbkqOHDmSdP0tLS3sggsuYCUlJUySJDZr1iz2rW99i3m93jxdwch+/vOfs+nTpzOz2cyWLl3K3n333cTHVqxYwW688cak5//hD39gc+bMYWazmS1YsIC9/PLLOR7x+Izmeu+5557EcysqKthll13G/vGPf+Rh1GMT33408C1+jTfeeCNbsWLFoNcsWbKEmc1mVltbm/S7bHSjvd5HHnmEzZw5k1ksFlZSUsJWrlzJ3njjjfwMfgxSXevAv79G/R2mYy4JIYQQA6M1akIIIcTAKFATQgghBkaBmhBCCDEwCtSEEEKIgVGgJoQQQgyMAjUhhBBiYBSoCSGEEAOjQE0IIYQYGAVqQkhKK1euxD333JPvYRAy6VGgJoTkhKqq+M///E/MmzcPVqsVJSUlOOecc/DUU0/le2iEGBodc0kIyYmHHnoITz75JH7xi1/grLPOgs/nw/vvv4+enp58D40QQ6OMmhAyop6eHtxwww0oLi6GzWbDpZdeikOHDiU959e//jVqampgs9lw9dVX49FHH0VRUVHi43/961/xta99Dddccw1mzJiBxYsX45ZbbsE3v/nNHF8NIYWFAjUhZEQ33XQT3n//ffz1r3/Fzp07wRjDZZddhmg0CgB45513cPvtt+PrX/869u3bh4suugjf//73kz5HZWUl3njjDXR0dOTjEggpWHR6FiEkpZUrV2LJkiW48847MWfOHLzzzjtYvnw5AKCrqws1NTV45plncM011+Daa6+F3+/Hpk2bEq//l3/5F2zatAm9vb0AgA8//BCf//zn0djYiAULFmD58uW46qqrcOmll+bj8ggpGJRRE0KG1dDQAFEUcc455yQemzJlCubOnYuGhgYAQGNjI5YuXZr0uoHvn3baaThw4ADeffddfPnLX0Z7ezuuvPJKfOUrX8n+RRBSwChQE0Jyhud5nH322bjnnnvw5z//GRs2bMBvfvMbHDlyJN9DI8SwKFATQoY1f/58KIqCXbt2JR7r6upCY2MjTjvtNADA3Llz8d577yW9buD7qcRfHwgEMjhiQiYW2p5FCBnW7NmzcdVVV+HWW2/Fk08+CafTifvvvx9Tp07FVVddBQC4++67ccEFF+DRRx/FlVdeiTfeeAOvvvoqOI5LfJ7Pf/7zOO+887B8+XJUVlbiyJEjWLduHebMmYN58+bl6/IIMTzKqAkhI3r66adx5pln4oorrsCyZcvAGMMrr7wCk8kEADjvvPPwxBNP4NFHH8XixYuxefNmfOMb34DFYkl8jtWrV+Oll17ClVdeiTlz5uDGG2/EvHnz8Prrr0MUKWcgZChU9U0IyYpbb70VH330Ef7+97/neyiEFDS6jSWEZMSPf/xjXHTRRbDb7Xj11VfxzDPP4Je//GW+h0VIwaOMmhCSEf/8z/+Mbdu2oa+vD7W1tbj77rtx++2353tYhBQ8CtSEEEKIgVExGSGEEGJgFKgJIYQQA6NATQghhBgYBWpCCCHEwChQE0IIIQZGgZoQQggxMArUhBBCiIFRoCaEEEIM7P8HTl3BzTXwH+QAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.lmplot(x=y_col, y=\"pred\", data=pred_df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "02eba13c-d357-48bb-8728-71889d4b6432",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:27:47.441065Z",
     "start_time": "2024-07-30T17:27:47.437310Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.33233338518579103"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r2_score(pred_df[y_col], pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "e2587ebb-b695-47a7-b8ea-db4a2e6b69f4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:27:49.410184Z",
     "start_time": "2024-07-30T17:27:49.407381Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5613578121061629"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "root_mean_squared_error(pred_df[y_col], pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fa2f33701239ff0a",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T17:20:48.311839Z",
     "start_time": "2024-07-30T17:20:48.310299Z"
    }
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
